<script setup lang="ts">
  import { getRolePage, updateRole, getRoleForm, addRole, deleteRoles, getRoleMenuIds, updateRoleMenus } from '@/api/role';
  import { getMenuOptions } from '@/api/menu';

  import { RolePageVO, RoleForm, RoleQuery } from '@/api/role/types';

  defineOptions({
    name: 'Role',
    inheritAttrs: false,
  });

  const queryFormRef = ref(ElForm);
  const roleFormRef = ref(ElForm);
  const menuRef = ref(ElTree);

  const loading = ref(false);
  const ids = ref<number[]>([]);
  const total = ref(0);

  const queryParams = reactive<RoleQuery>({
    pageNum: 1,
    pageSize: 10,
  });

  const roleList = ref<RolePageVO[]>();

  const dialog = reactive({
    title: '',
    visible: false,
  });

  const formData = reactive<RoleForm>({
    sort: 1,
    status: 1,
    code: '',
    name: '',
  });

  const rules = reactive({
    name: [{ required: true, message: '请输入角色名称', trigger: 'blur' }],
    code: [{ required: true, message: '请输入角色编码', trigger: 'blur' }],
    dataScope: [{ required: true, message: '请选择数据权限', trigger: 'blur' }],
    status: [{ required: true, message: '请选择状态', trigger: 'blur' }],
  });

  const menuDialogVisible = ref(false);

  const menuList = ref<OptionType[]>([]);

  interface CheckedRole {
    id?: number;
    name?: string;
  }
  let checkedRole: CheckedRole = reactive({});

  /** 查询 */
  function handleQuery() {
    loading.value = true;
    getRolePage(queryParams)
      .then(({ data }) => {
        roleList.value = data.list;
        total.value = data.total;
      })
      .finally(() => {
        loading.value = false;
      });
  }
  /** 重置查询 */
  function resetQuery() {
    queryFormRef.value.resetFields();
    queryParams.pageNum = 1;
    handleQuery();
  }

  /** 行checkbox 选中事件 */
  function handleSelectionChange(selection: any) {
    ids.value = selection.map((item: any) => item.id);
  }

  /** 打开角色表单弹窗 */
  function openDialog(roleId?: number) {
    dialog.visible = true;
    if (roleId) {
      dialog.title = '修改角色';
      getRoleForm(roleId).then(({ data }) => {
        Object.assign(formData, data);
      });
    } else {
      dialog.title = '新增角色';
    }
  }

  /** 角色保存提交 */
  function handleSubmit() {
    roleFormRef.value.validate((valid: any) => {
      if (valid) {
        loading.value = true;
        const roleId = formData.id;
        if (roleId) {
          updateRole(roleId, formData)
            .then(() => {
              ElMessage.success('修改成功');
              closeDialog();
              resetQuery();
            })
            .finally(() => (loading.value = false));
        } else {
          addRole(formData)
            .then(() => {
              ElMessage.success('新增成功');
              closeDialog();
              resetQuery();
            })
            .finally(() => (loading.value = false));
        }
      }
    });
  }

  /** 关闭表单弹窗 */
  function closeDialog() {
    dialog.visible = false;
    resetForm();
  }

  /** 重置表单 */
  function resetForm() {
    roleFormRef.value.resetFields();
    roleFormRef.value.clearValidate();

    formData.id = undefined;
    formData.sort = 1;
    formData.status = 1;
  }

  /** 删除角色 */
  function handleDelete(roleId?: number) {
    const roleIds = [roleId || ids.value].join(',');
    if (!roleIds) {
      ElMessage.warning('请勾选删除项');
      return;
    }

    ElMessageBox.confirm('确认删除已选中的数据项?', '警告', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    }).then(() => {
      loading.value = true;
      deleteRoles(roleIds)
        .then(() => {
          ElMessage.success('删除成功');
          resetQuery();
        })
        .finally(() => (loading.value = false));
    });
  }

  /** 打开分配菜单弹窗 */
  function openMenuDialog(row: RolePageVO) {
    const roleId = row.id;
    if (roleId) {
      checkedRole = {
        id: roleId,
        name: row.name,
      };
      menuDialogVisible.value = true;
      loading.value = true;

      // 获取所有的菜单
      getMenuOptions().then((response) => {
        menuList.value = response.data;
        // 回显角色已拥有的菜单
        getRoleMenuIds(roleId)
          .then(({ data }) => {
            const checkedMenuIds = data;
            checkedMenuIds.forEach((menuId) => menuRef.value.setChecked(menuId, true, false));
          })
          .finally(() => {
            loading.value = false;
          });
      });
    }
  }

  /** 角色分配菜单保存提交 */
  function handleRoleMenuSubmit() {
    const roleId = checkedRole.id;
    if (roleId) {
      const checkedMenuIds: number[] = menuRef.value.getCheckedNodes(false, true).map((node: any) => node.value);

      loading.value = true;
      updateRoleMenus(roleId, checkedMenuIds)
        .then(() => {
          ElMessage.success('分配权限成功');
          menuDialogVisible.value = false;
          resetQuery();
        })
        .finally(() => {
          loading.value = false;
        });
    }
  }

  onMounted(() => {
    handleQuery();
  });
</script>

<template>
  <div class="app-container">
    <div class="search-container">
      <el-form ref="queryFormRef" :model="queryParams" :inline="true">
        <el-form-item prop="keywords" label="关键字">
          <el-input v-model="queryParams.keywords" placeholder="角色名称" clearable @keyup.enter="handleQuery" />
        </el-form-item>

        <el-form-item>
          <el-button type="primary" @click="handleQuery"><i-ep-search />搜索</el-button>
          <el-button @click="resetQuery"><i-ep-refresh />重置</el-button>
        </el-form-item>
      </el-form>
    </div>

    <el-card shadow="never" class="table-container">
      <template #header>
        <el-button type="success" @click="openDialog()"><i-ep-plus />新增</el-button>
        <el-button type="danger" :disabled="ids.length === 0" @click="handleDelete()"><i-ep-delete />删除</el-button>
      </template>

      <el-table ref="dataTableRef" v-loading="loading" :data="roleList" highlight-current-row border @selection-change="handleSelectionChange">
        <el-table-column type="selection" width="55" align="center" />
        <el-table-column label="角色名称" prop="name" min-width="100" />
        <el-table-column label="角色编码" prop="code" width="150" />

        <el-table-column label="状态" align="center" width="100">
          <template #default="scope">
            <el-tag v-if="scope.row.status === 1" type="success">正常</el-tag>
            <el-tag v-else type="info">禁用</el-tag>
          </template>
        </el-table-column>

        <el-table-column label="排序" align="center" width="80" prop="sort" />

        <el-table-column fixed="right" label="操作" width="220">
          <template #default="scope">
            <el-button type="primary" size="small" link @click="openMenuDialog(scope.row)"> <i-ep-position />分配权限 </el-button>
            <el-button type="primary" size="small" link @click="openDialog(scope.row.id)"> <i-ep-edit />编辑 </el-button>
            <el-button type="primary" size="small" link @click="handleDelete(scope.row.id)"> <i-ep-delete />删除 </el-button>
          </template>
        </el-table-column>
      </el-table>

      <pagination v-if="total > 0" v-model:total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="handleQuery" />
    </el-card>

    <!-- 角色表单弹窗 -->
    <el-dialog v-model="dialog.visible" :title="dialog.title" width="500px" @close="closeDialog">
      <el-form ref="roleFormRef" :model="formData" :rules="rules" label-width="100px">
        <el-form-item label="角色名称" prop="name">
          <el-input v-model="formData.name" placeholder="请输入角色名称" />
        </el-form-item>

        <el-form-item label="角色编码" prop="code">
          <el-input v-model="formData.code" placeholder="请输入角色编码" />
        </el-form-item>

        <el-form-item label="数据权限" prop="dataScope">
          <el-select v-model="formData.dataScope">
            <el-option :key="0" label="全部数据" :value="0" />
            <el-option :key="1" label="部门及子部门数据" :value="1" />
            <el-option :key="2" label="本部门数据" :value="2" />
            <el-option :key="3" label="本人数据" :value="3" />
          </el-select>
        </el-form-item>

        <el-form-item label="状态" prop="status">
          <el-radio-group v-model="formData.status">
            <el-radio :label="1">正常</el-radio>
            <el-radio :label="0">停用</el-radio>
          </el-radio-group>
        </el-form-item>

        <el-form-item label="排序" prop="sort">
          <el-input-number v-model="formData.sort" controls-position="right" :min="0" style="width: 100px" />
        </el-form-item>
      </el-form>

      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="handleSubmit">确 定</el-button>
          <el-button @click="closeDialog">取 消</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 分配菜单弹窗  -->
    <el-dialog v-model="menuDialogVisible" :title="'【' + checkedRole.name + '】权限分配'" width="800px">
      <el-scrollbar v-loading="loading" max-height="600px">
        <el-tree ref="menuRef" node-key="value" show-checkbox :data="menuList" :default-expand-all="true">
          <template #default="{ data }">
            {{ data.label }}
          </template>
        </el-tree>
      </el-scrollbar>

      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="handleRoleMenuSubmit">确 定</el-button>
          <el-button @click="menuDialogVisible = false">取 消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>
